package com.agileboot.attendance.domain.record.service.impl;

import com.agileboot.attendance.domain.personnel.entity.PersonnelEntity;
import com.agileboot.attendance.domain.personnel.mapper.PersonnelMapper;
import com.agileboot.attendance.domain.record.db.entity.AttendanceRecord;
import com.agileboot.attendance.domain.record.db.mapper.AttendanceRecordMapper;
import com.agileboot.attendance.domain.record.dto.AttendanceStatisticsDTO;
import com.agileboot.attendance.domain.record.service.AttendanceStatisticsService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 考勤统计服务实现类
 */
@Service
@RequiredArgsConstructor
public class AttendanceStatisticsServiceImpl implements AttendanceStatisticsService {

    private final AttendanceRecordMapper attendanceRecordMapper;
    private final PersonnelMapper personnelMapper;

    @Override
    public List<AttendanceStatisticsDTO> getAttendanceStatistics(List<Long> personnelIds, LocalDate startDate, LocalDate endDate) {
        if (personnelIds == null || personnelIds.isEmpty()) {
            return new ArrayList<>();
        }

        // 查询人员信息
        List<PersonnelEntity> personnelList = personnelMapper.selectBatchIds(personnelIds);
        Map<Long, PersonnelEntity> personnelMap = personnelList.stream()
                .collect(Collectors.toMap(PersonnelEntity::getId, p -> p));

        // 查询考勤记录
        LambdaQueryWrapper<AttendanceRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(AttendanceRecord::getEmployeeId, personnelIds)
                .between(AttendanceRecord::getAttendanceDate, startDate, endDate);
        List<AttendanceRecord> records = attendanceRecordMapper.selectList(wrapper);

        // 按人员分组统计
        Map<Long, List<AttendanceRecord>> recordMap = records.stream()
                .collect(Collectors.groupingBy(AttendanceRecord::getEmployeeId));

        // 生成统计结果
        return personnelIds.stream().map(personnelId -> {
            AttendanceStatisticsDTO dto = new AttendanceStatisticsDTO();
            PersonnelEntity personnel = personnelMap.get(personnelId);
            if (personnel != null) {
                dto.setPersonnelId(personnelId);
                dto.setPersonnelName(personnel.getName());
                dto.setDailyRate(personnel.getDailyRate());
                dto.setOvertimeRate(personnel.getOvertimeRate());

                // 统计考勤数据
                List<AttendanceRecord> personnelRecords = recordMap.getOrDefault(personnelId, new ArrayList<>());
                dto.setAttendanceDays((int) personnelRecords.stream()
                        .filter(r -> "0".equals(r.getStatus()))  // 0表示正常考勤
                        .count());
                
                // 计算加班时长（小时）
                BigDecimal overtimeHours = personnelRecords.stream()
                        .filter(r -> r.getClockOutTime() != null && r.getClockInTime() != null)
                        .map(r -> {
                            long minutes = ChronoUnit.MINUTES.between(r.getClockInTime(), r.getClockOutTime());
                            // 超过8小时的部分算作加班
                            long overtimeMinutes = Math.max(0, minutes - 480);
                            return BigDecimal.valueOf(overtimeMinutes).divide(BigDecimal.valueOf(60), 2, BigDecimal.ROUND_HALF_UP);
                        })
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                dto.setOvertimeHours(overtimeHours);
            }
            return dto;
        }).collect(Collectors.toList());
    }
}
